package com.maxmlr.music.system.service.impl;

import com.google.common.collect.Lists;
import com.maxmlr.music.admin.service.UserService;
import com.maxmlr.music.common.base.BaseServiceImpl;
import com.maxmlr.music.common.config.MaxmlrConfig;
import com.maxmlr.music.common.constant.DictConstant;
import com.maxmlr.music.common.constant.FileType;
import com.maxmlr.music.common.util.FileUtil;
import com.maxmlr.music.system.dao.FilesMapper;
import com.maxmlr.music.system.entity.Files;
import com.maxmlr.music.system.service.FilesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author max
 * @version 1.0
 * @ClassName FilesServiceImpl
 * @Description 文件上传  服务实现类
 * @Copyright Copyright (c) 2020: www.maxmlr.com.
 * @since 2020-06-14
 */
@Slf4j
@Service
public class FilesServiceImpl extends BaseServiceImpl<FilesMapper, Files> implements FilesService {

    @Autowired
    private MaxmlrConfig maxmlrConfig;

    @Autowired
    private UserService userService;

    @Override
    public Files upload(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        DictConstant.FileTypes fileTypes = FileType.fileType(fileName);
        assert fileName != null;
        String fileRename = FileUtil.renameToId(fileName);
        String filePath = FileUtil.getFilePathByType(fileTypes);
        Files files = new Files();
        files.setType(fileTypes.getKey());
        files.setFileName(fileName);
        files.setUrl(filePath + fileRename);
        files.setCreateUserId(userService.getAdminUser().getId());
        files.setCreateDate(new Date());
        try {
            FileUtil.uploadFile(file, maxmlrConfig.getUploadPath() + filePath, fileRename);
        } catch (Exception e) {
            log.error("文件保存失败：" + e.getMessage(), e);
            throw new RuntimeException(e);
        }

        if (save(files)) {
            return files;
        }
        return null;
    }

    @Override
    public <T> T getFileById(T model, Function<T, Integer> idMapper, BiConsumer<T, String> urlMapper) {
        if (Objects.isNull(model)) {
            return model;
        }
        Integer id = idMapper.apply(model);
        if (Objects.isNull(id) || id < 1) {
            return model;
        }
        Files files = getById(id);
        if (Objects.nonNull(files)) {
            urlMapper.accept(model, files.getUrl());
        }
        return model;
    }

    @Override
    public <T> Collection<T> getFilesByIds(Collection<T> models, Function<T, Integer> idMapper,
                                           BiConsumer<T, String> urlMapper) {
        Collection<T> modelsOp = Optional.ofNullable(models).orElse(Lists.newArrayList());
        Set<Integer> ids = modelsOp.stream()
                .map(idMapper)
                .filter(p -> Objects.nonNull(p) && p > 0)
                .collect(Collectors.toSet());
        if (ids.isEmpty()) {
            return models;
        }
        Map<Integer, Files> filesMap = Optional.ofNullable(listByIds(ids))
                .orElse(Lists.newArrayList())
                .stream()
                .collect(Collectors.toMap(Files::getId, p -> p));
        modelsOp.forEach(p -> {
            Files files = filesMap.get(idMapper.apply(p));
            if (Objects.nonNull(files)) {
                urlMapper.accept(p, files.getUrl());
            }
        });
        return modelsOp;
    }
}
